package cn.com.hhrcw.web;

import cn.com.hhrcw.entity.*;
import cn.com.hhrcw.mapstruct.*;
import cn.com.hhrcw.params.EnNewsParams;
import cn.com.hhrcw.service.*;
import cn.com.hhrcw.utils.AgeUtil;
import cn.com.hhrcw.vo.EnNewsVO;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.aspect.annotation.AutoLog;
import org.jeecg.common.aspect.annotation.PermissionData;
import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.common.system.vo.LoginUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.function.Function;

/**
 * @program: recruit-boot-parent
 * @description: 消息
 * @author: JD
 * @create: 2020-11-11 10:15
 **/
@RestController
@RequestMapping("/enMessage")
@Slf4j
public class AdminMessageController {

    @Autowired
    AdminEnNewsConvert newsConvert;

    @Autowired
    AdminOpEntryHistoryConvert entryHistoryConvert;

    @Autowired
    IEnNewsService newsService;

    @Autowired
    IOpInterviewHistoryService historyService;

    @Autowired
    SysAnnouncementService sysAnnouncementService;

    @Autowired
    AdminSysAnnouncementConvert sysAnnouncementConvert;

    @Autowired
    IOpEntryHistoryService entryHistoryService;

    @Autowired
    IOpInterviewHistoryService interviewHistoryService;

    @Autowired
    AdminOpInterviewHistoryConvert interviewHistoryConvert;

    @Autowired
    IEnContactsService contactsService;

    @Autowired
    AdminEnContactsConvert contactsConvert;

    @Autowired
    IOpJobService jobService;

    @Autowired
    AdminOpJobConvert jobConvert;

    @Autowired
    IPiInfoService piInfoService;

    @Autowired
    AdminPiInfoConvert piInfoConvert;

    @Autowired
    IOpDeliveryHistoryService deliveryHistoryService;

    @Autowired
    AdminOpDeliveryHistoryConvert deliveryHistoryConvert;

    /**
     * 获取未读消息数量
     *
     * @return
     */
    @GetMapping("/getNotReadCount")
    @AutoLog(value = "未读消息数量查询",logType = 2,ty = "visit")
    public Result<Integer> getCount() {
        List<String> objId = new ArrayList<>();
        List<OpJob> jobs = jobService.lambdaQuery().eq(OpJob::getDelFlag, false).eq(OpJob::getSysFrom, 2).list();
        if (!CollectionUtils.isEmpty(jobs)) {

            List<String> jobIds = new ArrayList<>();
            jobs.forEach(e -> {
                jobIds.add(e.getId());
            });
            //投递

            List<OpDeliveryHistory> deliveryHistories = deliveryHistoryService.lambdaQuery().eq(OpDeliveryHistory::getDelFlag, false).in(OpDeliveryHistory::getJobId, jobIds).list();
            if (!CollectionUtils.isEmpty(deliveryHistories)) {
                deliveryHistories.forEach(d -> {
                    objId.add(d.getId());
                });
            }

            //面试
            List<OpInterviewHistory> histories = interviewHistoryService.lambdaQuery().eq(OpInterviewHistory::getDelFlag, false).in(OpInterviewHistory::getJobId, jobIds).list();
            if (!CollectionUtils.isEmpty(histories)) {
                histories.forEach(h -> {
                    objId.add(h.getId());
                });
            }

            //入职

            List<OpEntryHistory> entryHistories = entryHistoryService.lambdaQuery().eq(OpEntryHistory::getDelFlag, false).in(OpEntryHistory::getJobId, jobIds).list();
            if (!CollectionUtils.isEmpty(entryHistories)) {
                entryHistories.forEach(en -> {
                    objId.add(en.getId());
                });
            }
        }
        int count = 0;
        if (!CollectionUtils.isEmpty(objId)) {
            count = newsService.lambdaQuery().eq(EnNews::getAdminReadFlag, false).in(EnNews::getObjId, objId)
                    .eq(EnNews::getDelFlag, false).count();
        }
        return Result.ok(count);
    }


    /**
     * 根据id查询
     *
     * @param id 数据id
     * @return
     */
    @GetMapping(value = "/queryById")
    @ApiOperation(value = "根据id查询", notes = "根据id查询")
    @PermissionData
    public Result<EnNewsVO> queryById(String id) {
        EnNews enNews = newsService
                .lambdaQuery()
                .eq(EnNews::getId, id)
                .eq(EnNews::getDelFlag, false)
                .one();
        if (enNews == null) {
            throw new JeecgBootException("数据不存在");
        }
        return Result.ok(newsConvert.toVO(enNews));
    }

    /**
     * 发送消息
     *
     * @param params 请求参数
     * @return
     */
    @PostMapping(value = "/add")
    @AutoLog(logType = 2, ty = "insert", value = "发送消息")
    @ApiOperation(value = "添加", notes = "添加")
    @RequiresPermissions("enNews:add")
    public Result<?> add(@RequestBody @Valid EnNewsParams params) {
        LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        EnNews enNews = newsConvert.toEntity(params);
        enNews.setCreateBy(sysUser.getId());
        enNews.setCreateTime(DateUtil.date());
        enNews.setDelFlag(false);

        //enNews.setNo(super.sort("en_news", Constant.NO_SEED));//FIXME: 编号,可根据情况隐藏
        boolean saved = newsService.save(enNews);
        return saved ? Result.ok() : Result.error("添加失败");
    }

    /**
     * 编辑
     *
     * @param params 请求参数
     * @return
     */
    @PostMapping(value = "/edit")
    @AutoLog(logType = 2, ty = "visit", value = "修改消息")
    @ApiOperation(value = "编辑", notes = "编辑")
    @RequiresPermissions("enNews:edit")
    public Result<?> edit(@RequestBody @Valid EnNewsParams params) {
        LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();

        EnNews enNews = newsConvert.toEntity(params);
        enNews.setUpdateBy(sysUser.getId());
        enNews.setUpdateTime(DateUtil.date());

        boolean updated = newsService.updateById(enNews);
        return updated ? Result.ok() : Result.error("编辑失败");
    }


    /**
     * 批量删除
     *
     * @param id 数据id
     * @return
     */
    @GetMapping(value = "/delete")
    @AutoLog(logType = 2, ty = "delete", value = "删除消息")
    @ApiOperation(value = "批量删除", notes = "批量删除")
    @RequiresPermissions("enNews:delete")
    public Result delete(String[] id) {
        LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        LambdaUpdateWrapper<EnNews> updateWrapper = Wrappers.lambdaUpdate();
        updateWrapper.in(EnNews::getId, id)
                .set(EnNews::getDelFlag, true)
                .set(EnNews::getUpdateBy, sysUser.getUsername())
                .set(EnNews::getUpdateTime, DateUtil.date());

        boolean deleted = newsService.update(updateWrapper);
        return deleted ? Result.ok() : Result.error("删除失败");
    }


    /**
     * 消息列表,包含详情
     *
     * @param params
     * @return
     */
    @GetMapping("/message/list")
    @AutoLog(logType = 2, ty = "visit", value = "消息列表")
    public Result<Page<EnNewsVO>> messageList(EnNewsParams params) {
        LambdaQueryWrapper<EnNews> queryWrapper = new LambdaQueryWrapper<>();
        List<String> objId = new ArrayList<>();
        List<OpJob> jobs = jobService.lambdaQuery().eq(OpJob::getDelFlag, false).eq(OpJob::getSysFrom, 2).list();
        if (!CollectionUtils.isEmpty(jobs)) {

            List<String> jobIds = new ArrayList<>();
            jobs.forEach(e -> {
                jobIds.add(e.getId());
            });
            //投递

            List<OpDeliveryHistory> deliveryHistories = deliveryHistoryService.lambdaQuery().eq(OpDeliveryHistory::getDelFlag, false).in(OpDeliveryHistory::getJobId, jobIds).list();
            if (!CollectionUtils.isEmpty(deliveryHistories)) {
                deliveryHistories.forEach(d -> {
                    objId.add(d.getId());
                });
            }

            //面试
            List<OpInterviewHistory> histories = interviewHistoryService.lambdaQuery().eq(OpInterviewHistory::getDelFlag, false).in(OpInterviewHistory::getJobId, jobIds).list();
            if (!CollectionUtils.isEmpty(histories)) {
                histories.forEach(h -> {
                    objId.add(h.getId());
                });
            }

            //入职

            List<OpEntryHistory> entryHistories = entryHistoryService.lambdaQuery().eq(OpEntryHistory::getDelFlag, false).in(OpEntryHistory::getJobId, jobIds).list();
            if (!CollectionUtils.isEmpty(entryHistories)) {
                entryHistories.forEach(en -> {
                    objId.add(en.getId());
                });
            }
        }
        if (CollectionUtils.isEmpty(objId)) {
            return Result.ok(new Page<>());
        }
        queryWrapper/*.eq(EnNews::getReceiveId, sysUser.getId())*/.eq(EnNews::getDelFlag, false)
                //.eq(EnNews::getSendId, params.getUserId())
                .in(EnNews::getObjId, objId).orderByDesc(EnNews::getCreateTime).eq(EnNews::getReceiveType, 1);
        IPage<EnNews> page = newsService.page(params.page(), queryWrapper);
        Function<EnNews, EnNewsVO> function = news -> {
            EnNewsVO vo = newsConvert.toVO(news);
            //0投递1面试2录用3拒绝面试4接受面试5阅读6接受入职7拒绝入职8简历不合适通知9面试通过10面试未通过
            String two = "2";
            String six = "6";
            String seven = "7";
            String one = "1";
            String three = "3";
            String four = "4";
            if (two.equals(vo.getNewsType()) || six.equals(vo.getNewsType()) || seven.equals(vo.getNewsType())) {
                OpEntryHistory opEntryHistory = entryHistoryService.getById(vo.getObjId());

                if (opEntryHistory != null) {
                    vo.setEntryHistory(opEntryHistory);
                    EnContacts enContacts = contactsService.getById(opEntryHistory.getContactId());
                    vo.setEnContacts(enContacts);
                    OpJob opJob = jobService.getById(opEntryHistory.getJobId());
                    vo.setJob(opJob);

                    PiInfo piInfo = piInfoService.lambdaQuery().eq(PiInfo::getDelFlag, false).eq(PiInfo::getUserId, opEntryHistory.getUserId()).one();
                    vo.setPiInfo(piInfoConvert.toVO(piInfo));

                    if (piInfo != null) {
                        if (vo.getPiInfo().getJobTime() != null) {
                            int workYears = cn.com.hhrcw.utils.DateUtil.daysBetween(vo.getPiInfo().getJobTime(), new Date());
                            vo.getPiInfo().setWorkYears(workYears);
                        }
                    }
                }


            } else if (one.equals(vo.getNewsType()) || three.equals(vo.getNewsType()) || four.equals(vo.getNewsType())
                    || "9".equals(vo.getNewsType()) || "10".equals(vo.getNewsType())) {
                OpInterviewHistory interviewHistory = interviewHistoryService.getById(vo.getObjId());
                if (interviewHistory != null) {
                    String conId = interviewHistory.getContactId();
                    EnContacts enContacts = contactsService.getById(conId);
                    vo.setInterviewHistory(interviewHistory);
                    vo.setEnContacts(enContacts);

                    OpJob opJob = jobService.getById(interviewHistory.getJobId());
                    vo.setJob(opJob);

                    PiInfo piInfo = piInfoService.lambdaQuery().eq(PiInfo::getDelFlag, false).eq(PiInfo::getUserId, interviewHistory.getUserId()).one();
                    if (piInfo != null) {
                        vo.setPiInfo(piInfoConvert.toVO(piInfo));
                        if (vo.getPiInfo().getJobTime() != null) {
                            int workYears = cn.com.hhrcw.utils.DateUtil.daysBetween(vo.getPiInfo().getJobTime(), new Date());
                            vo.getPiInfo().setWorkYears(workYears);
                        }
                    }
                }

            }
            return vo;
        };
        return Result.ok((Page) page.convert(function));
    }

    /**
     * 招聘消息列表
     *
     * @param params
     * @return
     */
    @GetMapping("/list")
    @AutoLog(value = "招聘列表消息",logType = 2,ty = "visit")
    public Result<Page<EnNewsVO>> list(EnNewsParams params) {
        List<String> ids = new ArrayList<>();
        if (params.getType() == 0 || params.getType() == 1) {
            OpInterviewHistory opInterviewHistory = historyService.getById(params.getObjId());
            if (opInterviewHistory != null) {
                List<OpInterviewHistory> list = historyService.lambdaQuery().eq(OpInterviewHistory::getUserId, opInterviewHistory.getUserId())
                        .eq(OpInterviewHistory::getJobId, opInterviewHistory.getJobId()).eq(OpInterviewHistory::getDelFlag, false).list();
                if (!CollectionUtils.isEmpty(list)) {
                    list.forEach(e -> {
                        ids.add(e.getId());
                    });
                }
            }
            OpEntryHistory entryHistory = entryHistoryService.lambdaQuery().eq(OpEntryHistory::getUserId, params.getUserId()).eq(OpEntryHistory::getJobId, opInterviewHistory.getJobId()).eq(OpEntryHistory::getDelFlag, false).one();
            if (entryHistory != null) {
                ids.add(entryHistory.getId());
            }
            ids.add(entryHistory.getId());
        } else {
            List<OpInterviewHistory> opInterviewHistory = historyService.lambdaQuery().eq(OpInterviewHistory::getUserId, params.getUserId())
                    .eq(OpInterviewHistory::getJobId, params.getObjId()).eq(OpInterviewHistory::getDelFlag, false).list();
            if (!CollectionUtils.isEmpty(opInterviewHistory)) {
                opInterviewHistory.forEach(e -> {
                    ids.add(e.getId());
                });
            }
            List<OpEntryHistory> entryHistory = entryHistoryService.lambdaQuery().eq(OpEntryHistory::getUserId, params.getUserId()).eq(OpEntryHistory::getJobId, params.getObjId()).eq(OpEntryHistory::getDelFlag, false).list();
            if (!CollectionUtils.isEmpty(entryHistory)) {
                entryHistory.forEach(e -> {
                    ids.add(e.getId());
                });
            }
            List<OpDeliveryHistory> opDeliveryHistory = deliveryHistoryService.lambdaQuery().eq(OpDeliveryHistory::getUserId, params.getUserId()).eq(OpDeliveryHistory::getJobId, params.getObjId()).eq(OpDeliveryHistory::getDelFlag, false).list();
            if (!CollectionUtils.isEmpty(opDeliveryHistory)) {
                opDeliveryHistory.forEach(e -> {
                    ids.add(e.getId());
                });
            }
        }

        if (CollectionUtils.isEmpty(ids)) {
            return Result.ok((new Page<>()));
        }

        LambdaQueryWrapper<EnNews> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper/*.eq(EnNews::getReceiveId, sysUser.getId())*/.eq(EnNews::getDelFlag, false)
                //.eq(EnNews::getSendId, params.getUserId())
                .in(EnNews::getObjId, ids).orderByDesc(EnNews::getCreateTime);
        IPage<EnNews> page = newsService.page(params.page(), queryWrapper);
        Function<EnNews, EnNewsVO> function = news -> newsConvert.toVO(news);
        return Result.ok((Page) page.convert(function));
    }

}
